const fs = require('fs');
const Path = require('path');
const os = require('os');
const {
    sync
} = require('resolve');
const StandardModules = new Set(['assert', 'buffer', 'child_process', 'cluster', 'console', 'constants', 'crypto',
    'dgram', 'dns', 'domain', 'events', 'fs', 'http', 'https', 'module', 'net', 'os', 'path', 'punycode',
    'process', 'querystring', 'readline', 'repl', 'stream', '_stream_duplex', '_stream_passthrough',
    '_stream_readable', '_stream_transform', '_stream_writable', 'string_decoder', 'sys', 'timers', 'tls',
    'tty', 'url', 'util', 'vm', 'zlib', 'ZPackStub'
]);

function isSysPath(s) {
    return StandardModules.has(s);
}

function isExternalPath(s, opt) {
    return opt.external && opt.external.includes(s);
}

function isSubDir(dir1, dir2) {
    if (os.platform().toLowerCase().startsWith('win')) {
        dir1 = dir1.toLowerCase().replace(/\\/g, '/');
        dir2 = dir2.toLowerCase().replace(/\\/g, '/');
    }
    return dir2.startsWith(dir1);
}


function appendJs(s, opt) {
    if (isSysPath(s) || isExternalPath(s, opt)) {
        return s;
    }
    if (!s.toLowerCase().endsWith('.js')) {
        return s + '.js';
    } else {
        return s;
    }
}

function normalize(path, opt) {
    path = appendJs(path, opt).replace(/\\/g, '/');
    if (path.endsWith('/')) {
        path = path.slice(0, -1);
    }
    return path;
}

function resolve(basedir, name, opt) {
    //如果是系统库或者外部库，直接返回
    if (isSysPath(name) || isExternalPath(name, opt)) {
        return {
            src: name,
            target: name,
            url: name,
            type: isSysPath(name) ? 'system' : 'external',
        };
    }
    //获取依赖的实际路径
    var src = sync(name, {
        basedir,
        extensions: opt.ext
    });
    src = fs.realpathSync(src);

    //安装host
    for (let dir in opt.hosts) {
        let rdir = fs.realpathSync(dir);
        if (isSubDir(rdir, src)) {
            let out = Path.join(opt.hosts[dir], src.substring(rdir.length));
            return {
                src,
                target: normalize(src, opt),
                url: normalize(out, opt),
                type: 'normal'
            };
        }
    }
    throw new Error("host for '" + name + "' configured");
}

module.exports = {
    resolve
};